<?php
/**
 * Created by PhpStorm.
 * User: serenehaly
 * Date: 2018/2/6
 * Time: 15:31
 */

namespace app\api\service;


use app\lib\exception\TokenException;
use app\lib\exception\WeChatException;
use think\Exception;
use app\api\model\User as UserModel;

class UserToken extends Token
{
    protected $code;
    protected $wxAppID;
    protected $wxAppSecret;
    protected $wxLoginUrl;

    public function __construct($code)
    {
        $this->code = $code;
        $this->wxAppID = config('wx.app_id');
        $this->wxAppSecret = config('wx.app_secret');
        $this->wxLoginUrl = sprintf(config('wx.user_login_url'), $this->wxAppID, $this->wxAppSecret, $this->code);
    }

    // 获取token值
    public function get()
    {
        $result = curl_get($this->wxLoginUrl);
        $wxResult = json_decode($result, true);
        if (empty($wxResult)) {
            throw new Exception('获取session_key及openID时异常，微信内部错误');
        } else {
            $loginFail = array_key_exists('errcode', $wxResult);
            if ($loginFail) {
                $this->processLoginError($wxResult);
            } else {
                $token = $this->grantToken($wxResult);
                return $token;
            }
        }
    }

    // 微信小程序登录错误异常处理
    private function processLoginError($wxResult)
    {
        throw new WeChatException(
            [
                'msg' => $wxResult['errmsg'],
                'errorCode' => $wxResult['errcode']
            ]);
    }

    //将cache键值对，并返回token
    private function grantToken($wxResult)
    {
        $openid = $wxResult['openid'];
        $user = UserModel::getUserByOpenid($openid);
        if ($user) {
            $uid = $user->id;
        } else {
            $newUser = UserModel::addUser($openid);
            $uid = $newUser->id;
        }
        $cacheValue = $this->prepareCacheValue($wxResult, $uid);
        $token = $this->saveCache($cacheValue);
        return $token;
    }

    //缓存
    private function saveCache($cacheValue)
    {
        $key = self::generateToken();
        $value = json_encode($cacheValue);
        $expire_in = config('setting.token_expire_in');
        $result = cache($key, $value, $expire_in); // return true/false
        if (!$result) {
            throw new TokenException([
                'msg' => '服务器缓存异常',
                'errorCode' => 10005
            ]);
        } else {
            /*return [
                'cache' => json_decode(cache($key)),
                'token' => $key
            ];*/
            // 结果集
            /*{
                "cache": {
                    "session_key": "gxmshE26WAHE1uWo+W8ouw==",
                    "expires_in": 7200,
                    "openid": "o9oQP0aPYFEMFfyaFqhtx8J_LrYE",
                    "uid": 1,
                    "scope": 16
                },
                "token": "391cb3b1874918cc2cfc98764099e064"
            }*/
            return $key;
        }
    }

    //处理cache键值对对应的值
    private function prepareCacheValue($wxResult, $uid)
    {
        $cacheValue = $wxResult;
        $cacheValue['uid'] = $uid;
        $cacheValue['scope'] = 16;
        return $cacheValue;
    }
}